
import 'dart:ui';

import 'package:flame/components.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';

import '../util/effect_utils.dart';
import 'card.dart';
import 'pile.dart';

class Operation {

  Operation(this.cards, this.from, this.to);

  List<Card> cards;
  Pile from;
  Pile to;

  VoidCallback? preProcess;
  VoidCallback? middleProcess;
  VoidCallback? postProcess;

  VoidCallback? preRevoke;
  VoidCallback? middleRevoke;
  VoidCallback? postRevoke;

  // effect
  bool hasMove = false;
  bool hasRevokeMove = false;
  double speed = 10.0;
  List<Vector2> fromPositions = [];
  List<Vector2> toPositions = [];

  static Operation init(
    List<Card> cards,
    Pile from,
    Pile to,
    List<Vector2> fromPositions,
    List<Vector2> toPositions,
    double speed) {
    
    return Operation(cards, from, to)
     ..hasMove = true
     ..hasRevokeMove = true
     ..fromPositions = fromPositions
     ..toPositions = toPositions
     ..speed = speed;
  }

  Future<void> proceed() async {
    preProcess?.call();
    await motion(false);
    from.removeCard(cards);
    middleProcess?.call();
    to.acquireCard(cards);
    postProcess?.call();
  }

  Future<void> revoke() async {
    preRevoke?.call();
    await motion(true);
    to.removeCard(cards);
    middleRevoke?.call();
    from.acquireCard(cards);
    postRevoke?.call();
  }

  Future<void> motion(bool revoke) async {
    if(hasMove && !revoke) {
      await EffectUtils.doMove(
        speed: speed,
        cards,
        toPositions,
      );
    } else if(hasRevokeMove && revoke) {
      await EffectUtils.doMove(
        speed: speed,
        cards,
        fromPositions,
      );
    }
  }
}